<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>方块战斗</title>
    <style>
        body { margin: 0; overflow: hidden; }
        canvas { display: block; }
        #loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: white;
            font-size: 24px;
            display: none; /* 默认隐藏 */
        }
        #killCounter, #playerHealth,#hlep {
            position: absolute;
            top: 10px;
            left: 10px;
            color: white;
            font-size: 20px;
            z-index: 1; /* 确保在最上层 */
        }
        #playerHealth {
            top: 40px; /* 位于击杀数下方 */
        }
        #hlep {
            top: 60px; /* 位于生命值下方 */
        }
    </style>
    <script type="importmap">
        {
            "imports": {
                "three": "./node_modules/three/build/three.module.js"
            }
        }
    </script>
</head>
<body>
    
    <div id="loading">点击页面以开始游戏并锁定光标...</div>
    <div id="killCounter">击杀数: 0</div>
    <div id="playerHealth">生命值: 100</div>
    <div id="hlep">鼠标左键发射子弹，w前进s后退a左移动d右移动</div> <!-- 玩家生命值显示 -->
    <audio id="backgroundMusic" src="bj.mp3" loop></audio> <!-- 背景音乐 -->
    <audio id="shootSound" src="kq.mp3"></audio> <!-- 开枪音效 -->
    <audio id="movingSound" src="yd.mp3" loop></audio> <!-- 移动音效 -->
    <audio id="killSound1" src="./连杀音效/kill1.mp3"></audio> <!-- 1杀音效 -->
    <audio id="killSound2" src="./连杀音效/kill2.mp3"></audio> <!-- 2杀音效 -->
    <audio id="killSound3" src="./连杀音效/kill3.mp3"></audio> <!-- 3杀音效 -->
    <audio id="killSound4" src="./连杀音效/kill4.mp3"></audio> <!-- 4杀音效 -->
    <audio id="killSound5" src="./连杀音效/kill5.mp3"></audio> <!-- 5杀音效 -->
    <audio id="killSound6" src="./连杀音效/暗区突围.mp3"></audio> <!-- 6杀音效 -->
    <audio id="multikillSound" src="./连杀音效/暗区突围.mp3"></audio> <!-- 连杀音效 -->

    <script type="module">
        import * as THREE from 'three'; // 通过 importmap 导入 three.js
        import { PointerLockControls } from './node_modules/three/examples/jsm/controls/PointerLockControls.js'; // 本地加载 PointerLockControls

        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 添加天空盒
        const skyTexture = new THREE.TextureLoader().load('/材质/tk.jpg'); // 载入天空纹理
        const skyMaterial = new THREE.MeshBasicMaterial({ map: skyTexture, side: THREE.BackSide });
        const skyGeometry = new THREE.SphereGeometry(100, 32, 32);
        const skyBox = new THREE.Mesh(skyGeometry, skyMaterial);
        scene.add(skyBox);

        // 设置地面
        const planeGeometry = new THREE.PlaneGeometry(100, 100);
        const planeTexture = new THREE.TextureLoader().load('/材质/ground_texture.jpg'); // 使用自定义地面纹理
        const planeMaterial = new THREE.MeshStandardMaterial({ map: planeTexture });
        const plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.rotation.x = -Math.PI / 2; // 修正地面方向
        scene.add(plane);

        // 随机生成障碍物
        const obstacles = [];
        const obstacleTexture = new THREE.TextureLoader().load('/材质/obstacle_texture.jpg'); // 使用自定义障碍物纹理
        for (let i = -50; i < 50; i += 5) {
            for (let j = -50; j < 50; j += 5) {
                if (Math.random() > 0.7) {
                    const obstacleGeometry = new THREE.BoxGeometry(3, Math.random() * 5 + 1, 3);
                    const obstacleMaterial = new THREE.MeshStandardMaterial({ map: obstacleTexture });
                    const obstacle = new THREE.Mesh(obstacleGeometry, obstacleMaterial);
                    obstacle.position.set(i, obstacle.geometry.parameters.height / 2, j);
                    obstacles.push(obstacle);
                    scene.add(obstacle);
                }
            }
        }

        const controls = new PointerLockControls(camera, document.body);
        const loadingDiv = document.getElementById('loading'); // 定义加载界面
        const killCounterDiv = document.getElementById('killCounter'); // 定义击杀计数器
        const playerHealthDiv = document.getElementById('playerHealth'); // 定义玩家生命值显示
        let killCount = 0; // 初始化击杀计数
        let playerHealth = 100; // 玩家初始生命值
        let enemyKillCount = 0; // 连杀计数
        let isMoving = { forward: false, backward: false, left: false, right: false }; // 移动状态
        let movingSoundPlaying = false; // 移动音效状态

        document.addEventListener('click', () => {
            controls.lock(); // 锁定鼠标
            loadingDiv.style.display = 'none'; // 隐藏加载界面
            document.getElementById('backgroundMusic').volume = 0.5; // 将背景音乐音量设置为50%
            document.getElementById('backgroundMusic').play(); // 播放背景音乐
        });

        controls.addEventListener('lock', () => {
            document.body.style.cursor = 'none'; // 隐藏光标
        });

        controls.addEventListener('unlock', () => {
            document.body.style.cursor = 'default'; // 恢复光标
        });

        document.addEventListener('keydown', (event) => {
            switch (event.key) {
                case 'w': isMoving.forward = true; break;
                case 's': isMoving.backward = true; break;
                case 'a': isMoving.left = true; break;
                case 'd': isMoving.right = true; break;
            }
        });

        document.addEventListener('keyup', (event) => {
            switch (event.key) {
                case 'w': isMoving.forward = false; break;
                case 's': isMoving.backward = false; break;
                case 'a': isMoving.left = false; break;
                case 'd': isMoving.right = false; break;
            }
        });
        //敌人初始状态
        const enemies = [];
        function createEnemy() {
            const enemyGeometry = new THREE.BoxGeometry(1, 1, 1);
            const enemyMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
            const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
            enemy.health = 100;
            enemy.position.set(Math.random() * 50 - 25, 0.5, Math.random() * 50 - 25);
            enemy.direction = new THREE.Vector3(Math.random() - 0.5, 0, Math.random() - 0.5).normalize();
            enemies.push(enemy);
            scene.add(enemy);
        }
        setInterval(createEnemy, 5000); // 每隔 5 秒生成一个敌人

        const bullets = [];
        document.addEventListener('mousedown', () => {
            fireBullet();
            playShootSound(); // 开枪音效
        });

        function fireBullet() {
            const bulletGeometry = new THREE.SphereGeometry(0.1, 8, 8);
            const bulletMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
            const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial);
            bullet.position.copy(camera.position);

            const bulletDirection = new THREE.Vector3();
            camera.getWorldDirection(bulletDirection);
            bullet.userData.direction = bulletDirection;
            bullets.push(bullet);
            scene.add(bullet);
        }

        function updateBullets() {
            bullets.forEach((bullet, index) => {
                bullet.position.add(bullet.userData.direction.clone().multiplyScalar(0.5));
                enemies.forEach((enemy, enemyIndex) => {
                    if (bullet.position.distanceTo(enemy.position) < 0.5) {
                        enemy.health -= 20; // 敌人受到伤害
                        bullets.splice(index, 1); // 删除子弹
                        scene.remove(bullet);
                        if (enemy.health <= 0) {
                            enemy.material.color.set(0x00ff00); // 将敌人变成绿色
                            enemies.splice(enemyIndex, 1); // 删除敌人
                            killCount++; // 增加击杀计数
                            enemyKillCount++; // 增加连杀计数
                            killCounterDiv.textContent = `击杀数: ${killCount}`;
                            playKillSound(killCount); // 播放击杀音效
                            if (enemyKillCount % 2 === 0) {
                                playerHealth = Math.min(100, playerHealth + 20); // 每两杀回复20血
                                playerHealthDiv.textContent = `生命值: ${playerHealth}`;
                            }
                        }
                    }
                });

                // 删除超出范围的子弹
                if (bullet.position.length() > 100) {
                    scene.remove(bullet);
                    bullets.splice(index, 1);
                }
            });
        }

        // 敌人发射子弹
        const enemyBullets = [];
        function fireEnemyBullet(enemy) {
            const bulletGeometry = new THREE.SphereGeometry(0.1, 8, 8);
            const bulletMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
            const bullet = new THREE.Mesh(bulletGeometry, bulletMaterial);
            bullet.position.copy(enemy.position);

            const bulletDirection = new THREE.Vector3();
            bulletDirection.subVectors(camera.position, enemy.position).normalize();
            bullet.userData.direction = bulletDirection;
            enemyBullets.push(bullet);
            scene.add(bullet);
        }

        function updateEnemyBullets() {
            enemyBullets.forEach((bullet, index) => {
                bullet.position.add(bullet.userData.direction.clone().multiplyScalar(0.3));

                const distanceToPlayer = bullet.position.distanceTo(camera.position);
                if (distanceToPlayer < 0.5) {
                    playerHealth -= 10;
                    playerHealthDiv.textContent = `生命值: ${playerHealth}`; // 更新生命值显示
                    scene.remove(bullet);
                    enemyBullets.splice(index, 1);

                    if (playerHealth <= 0) {
                        alert('游戏结束！');
                        location.reload(); // 游戏结束，刷新页面重新开始
                    }
                }

                // 删除超出范围的子弹
                if (bullet.position.length() > 100) {
                    scene.remove(bullet);
                    enemyBullets.splice(index, 1);
                }
            });
        }

        // 敌人移动逻辑
        function updateEnemies() {
            enemies.forEach((enemy) => {
                const directionToPlayer = new THREE.Vector3();
                directionToPlayer.subVectors(camera.position, enemy.position).normalize();
                
                // 移动逻辑，防止与障碍物相撞
                const obstacleCollision = obstacles.some((obstacle) => {
                    const obstacleBox = new THREE.Box3().setFromObject(obstacle);
                    const enemyBox = new THREE.Box3().setFromObject(enemy);
                    return obstacleBox.intersectsBox(enemyBox);
                });

                if (!obstacleCollision) {
                    enemy.position.add(directionToPlayer.multiplyScalar(0.02)); // 敌人向玩家移动
                }

                // 每隔 1 秒发射子弹
                if (Math.random() < 0.01) {
                    fireEnemyBullet(enemy);
                }
            });
        }
        function checkPlayerCollision() {
            let collision = false;
            obstacles.forEach((obstacle) => {
                const obstacleBox = new THREE.Box3().setFromObject(obstacle);
                const playerBox = new THREE.Box3().setFromCenterAndSize(camera.position, new THREE.Vector3(1, 1, 1));
                if (obstacleBox.intersectsBox(playerBox)) {
                    collision = false; // 检测到碰撞
                }
            });
            return collision;
        }


        const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 方向光
        directionalLight.position.set(0, 10, 10);
        scene.add(directionalLight);

        camera.position.set(0, 1.7, 5); // 调整摄像头高度至合理值

        const clock = new THREE.Clock();

        function animate() {
            requestAnimationFrame(animate);

            const delta = clock.getDelta();
            if (isMoving.forward || isMoving.backward || isMoving.left || isMoving.right) {
                const speed = 5 * delta;
                if (isMoving.forward && !checkPlayerCollision()) controls.moveForward(speed);
                if (isMoving.backward && !checkPlayerCollision()) controls.moveBackward(speed);
                if (isMoving.left && !checkPlayerCollision()) controls.moveRight(-speed);
                if (isMoving.right && !checkPlayerCollision()) controls.moveRight(speed);

                if (!movingSoundPlaying) {
                    document.getElementById('movingSound').play();
                    movingSoundPlaying = true;
                }
            } else if (movingSoundPlaying) {
                document.getElementById('movingSound').pause();
                movingSoundPlaying = false;
            }

            updateBullets();
            updateEnemies();
            updateEnemyBullets();

            renderer.render(scene, camera);
        }
        animate();

        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        function playShootSound() {
            const shootSound = document.getElementById('shootSound');
            shootSound.currentTime = 0; // 重置音效时间
            shootSound.play(); // 播放开枪音效
        }

        function playKillSound(count) {
            let sound;
            if (count <= 6) {
                sound = document.getElementById(`killSound${count}`);
                sound.currentTime = 0; // 重置音效时间
                sound.play(); // 播放相应的击杀音效
            } else {
                sound = document.getElementById('killSound6');
                sound.currentTime = 0; // 重置音效时间
                sound.play(); // 循环播放6杀音效
            }
        }
        
    </script>
</body>
</html>
